namespace pack {
class Reader {
 protected:
  bool is_good;
 protected:
  net::IBuffer* buffer;
 public:
  Reader(net::IBuffer* buffer);
  ~Reader();
  public:
   operator bool();
   Reader& operator>>(uint32_t& v);
   Reader& operator>>(std::string& v);
   Reader& operator>>(std::list<uint32_t>& v);
   Reader& operator>>(std::list<std::string>& v);
   template<typename T>
    Reader& operator>>(T& v);
   template<typename T>
    Reader& operator>>(std::list<T>& v);
   template<typename T>
    Reader& operator>>(std::vector<T>& v);
   template<typename T>
    Reader& operator>>(std::set<T>& v);
   template<typename T1, typename T2>
    Reader& operator>>(std::map<T1, T2>& v);
 };
 template<typename T>
  Reader& Reader::operator>>(T& v) {
   v.Deserialize(buffer);
   return *this;
  }
 template<typename T>
  Reader& Reader::operator>>(std::list<T>& v) {
   size_t size = 0;
   buffer->Read((char*)&size, sizeof(size_t));
   for(size_t i = 0; i < size; i++) {
    T temp;
    temp.Deserialize(buffer);
    v.push_back(temp);
   }
   return *this;
  }
 template<typename T>
  Reader& Reader::operator>>(std::vector<T>& v) {
   size_t size = 0;
   buffer->Read((char*)&size, sizeof(size_t));
   for(size_t i = 0; i < size; i++) {
    T temp;
    this->operator>>(temp);
    v.push_back(temp);
   }
   return *this;
  }
 template<typename T>
  Reader& Reader::operator>>(std::set<T>& v) {
   size_t size = 0;
   buffer->Read((char*)&size, sizeof(size_t));
   for(size_t i = 0; i < size; i++) {
    T temp;
    this->operator>>(temp);
    v.insert(temp);
   }
   return *this;
  }
 template<typename T1, typename T2>
  Reader& Reader::operator>>(std::map<T1, T2>& v) {
   size_t size = 0;
   buffer->Read((char*)&size, sizeof(size_t));
   for(size_t i = 0; i < size; i++) {
    T1 key;
    T2 val;
    this->operator>>(key)>>(val);
    v.insert(std::make_pair(key, val));
   }
   return *this;
  }
}
namespace pack {
class Writer {
 protected:
  net::IBuffer* buffer;
 public:
  Writer(net::IBuffer* buffer);
  ~Writer();
 public:
  Writer& operator<<(uint32_t v);
  Writer& operator<<(std::string& v);
  Writer& operator<<(std::list<uint32_t>& v);
  Writer& operator<<(std::list<std::string>& v);
  template<typename T>
   Writer& operator<<(T& v);
  template<typename T>
   Writer& operator<<(std::list<T>& v);
  template<typename T>
   Writer& operator<<(std::vector<T>& v);
  template<typename T>
   Writer& operator<<(std::set<T>& v);
  template<typename T1, typename T2>
   Writer& operator<<(std::map<T1, T2>& v);
 };
 template<typename T>
  Writer& Writer::operator<<(T& v) {
   v.Serialize(buffer);
   return *this;
  }
 template<typename T>
  Writer& Writer::operator<<(std::list<T>& v) {
   size_t size = v.size();
   buffer->Write((char*)&size, sizeof(size_t));
   for(typename::std::list<T>::iterator it = v.begin(); it != v.end(); it++) {
    it->Serialize(buffer);
   }
   return *this;
  }
 template<typename T>
  Writer& Writer::operator<<(std::vector<T>& v) {
   size_t size = v.size();
   buffer->Write((char*)&size, sizeof(size_t));
   for(typename::std::vector<T>::iterator it = v.begin(); it != v.end(); it++) {
    this->operator<<(*it);
   }
   return *this;
  }
 template<typename T>
  Writer& Writer::operator<<(std::set<T>& v) {
   size_t size = v.size();
   buffer->Write((char*)&size, sizeof(size_t));
   for(typename::std::set<T>::iterator it = v.begin(); it != v.end(); it++) {
    this->operator<<(*it);
   }
   return *this;
  }
 template<typename T1, typename T2>
  Writer& Writer::operator<<(std::map<T1, T2>& v) {
   size_t size = v.size();
   buffer->Write((char*)&size, sizeof(size_t));
   for(typename::std::map<T1, T2>::iterator it = v.begin(); it != v.end(); it++) {
    this->operator<<(it->first)<<(it->second);
   }
   return *this;
  }
}
namespace pack {
class IPacket;
class Request {
 protected:
  uint32_t uri;
  uint32_t size;
 private:
  char* buf;
  uint32_t buf_size;
 protected:
  net::IBuffer* internal_buffer;
  net::IBuffer* external_buffer;
 public:
  Request(net::IBuffer* buffer);
  ~Request();
 private:
  void DestroyBuf();
  void ReallocBuf(uint32_t size);
 public:
  uint32_t GetUri();
  bool GetPack();
  bool Pack(IPacket* packet);
  bool UnPack(IPacket* packet);
};
}
namespace pack {
class Reader;
class Writer;
class IPacket {
 public:
  virtual uint32_t GetUri() = 0;
  virtual bool Pack(Writer& writer) = 0;
  virtual bool UnPack(Reader& reader) = 0;
};
}
namespace pack {
class StringBuffer : public net::IBuffer {
 public:
  virtual void Hold();
  virtual void Commit();
  virtual void Revert();
  virtual char* GetData();
  virtual uint32_t GetSize();
  virtual uint32_t Read(char* buf, uint32_t len);
  virtual uint32_t Write(char* buf, uint32_t len);
};
}
